library MoveSpeedUpBuff initializer Init requires entities, utils
    
    globals
        public integer RAW_CODE = 'AB11'
        public integer BUFF_ID = 'B111'
    endglobals

    struct MoveSpeedUpBuff extends array

        delegate Buff m_buff

        method setSpeedRate takes real speedRate returns nothing
            set this.m_real1 = speedRate
        endmethod

        method getSpeedRate takes nothing returns real
            return this.m_real1
        endmethod

        method setSpeedValue takes real speedValue returns nothing
            set this.m_real2 = speedValue
        endmethod

        method getSpeedValue takes nothing returns real
            return this.m_real2
        endmethod

        static method create takes nothing returns thistype
            local thistype this = thistype(Buff.create(BUFF_ID))
            set this.m_buff = Buff(this)
            set this.m_buffKind = BUFF_POSITIVE

            return this
        endmethod

    endstruct


    private function OnApply takes integer dt returns nothing
        local MoveSpeedUpBuff bfd = MoveSpeedUpBuff(dt)
        local Unit ud = Unit.get(bfd.m_unit)

        if bfd.m_buffId == BUFF_ID then
            call bfd.setSpeedValue(bfd.getSpeedRate() * ud.getMoveSpeed())
            call ud.addMoveSpeed(bfd.getSpeedValue())
        endif
    endfunction

    private function OnRemove takes integer dt returns nothing
        local MoveSpeedUpBuff bfd = MoveSpeedUpBuff(dt)
        local Unit ud = Unit.get(bfd.m_unit)

        if bfd.m_buffId == BUFF_ID then
            call ud.addMoveSpeed(-bfd.getSpeedValue())
        endif
    endfunction

    private function OnExpire takes nothing returns nothing
        local Dto dto = GetTimerData(GetExpiredTimer())
        local Buff bfd = Buff(dto.m_data)
        local Unit ud = Unit.get(bfd.m_unit)

        call ud.removeBuff(bfd)
        
        call bfd.destroy()
        call dto.destroy()
    endfunction

    private function OnActive takes integer dt returns nothing
        local Buff bfd = Buff(dt)
        local Dto dto

        if bfd.m_buffId == BUFF_ID then
            set bfd.m_rawCode = RAW_CODE
            
            set dto = Dto.create()
            set dto.m_data = bfd

            call TimerStart(dto.getTimer(), bfd.m_duration, false, function OnExpire)
        endif
    endfunction

    private function Init takes nothing returns nothing
        call RegisterBuffActiveResponse(OnActive)
        call RegisterBuffApplyResponse(OnApply)
        call RegisterBuffRemoveResponse(OnRemove)
    endfunction
    
endlibrary
